<?php

namespace MoChat\App\Client\Action\Dashboard\FollowRecord;

use Hyperf\DbConnection\Db;
use MoChat\App\Call\Constants\ClientTypeCode;
use MoChat\App\Client\Constants\ClientFollowRecordTypeCode;
use MoChat\App\Client\Logic\Detail\HeadLogic;
use MoChat\Framework\Action\AbstractAction;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\Middlewares;
use Hyperf\HttpServer\Annotation\RequestMapping;
use MoChat\App\Common\Middleware\DashboardAuthMiddleware;
use MoChat\App\Rbac\Middleware\PermissionMiddleware;
use MoChat\App\Client\Logic\FollowRecord\IndexLogic;
use MoChat\Framework\Constants\ErrorCode;
use MoChat\Framework\Exception\CommonException;
use MoChat\Framework\Request\ValidateSceneTrait;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;

/**
 * 跟进记录-列表
 * @Controller
 */
class FollowListExport extends AbstractAction
{
    use ValidateSceneTrait;

    /**
     * @Middlewares({
     *     @Middleware(DashboardAuthMiddleware::class),
     * })
     *
     * @RequestMapping(path="/dashboard/client/followRecord/listExoprt", methods="GET")
     */
    public function handle(): array
    {
        ini_set("max_execution_time", "0");
        ini_set("memory_limit", "5G");
        $user = user();
        if (empty($user)) {
            throw new CommonException(ErrorCode::AUTH_UNAUTHORIZED, '登入异常请重新登入');
        }
        $data = $this->request->all();
        $list = Db::table('client_follow_record as record')
            ->when(!empty($data['followUp']), function ($query) use ($data) {
                //类型（1：电话。2：面访。3：企业微信）
                $query->where('record.type', '=', $data['followUp']);
            })
            ->when(!empty($data['enterpriseId']), function ($query) use ($data) {
                $query->where('client.enterprise_name', 'like', '%'.$data['enterpriseId'].'%');
            })
            ->when(!empty($data['employeeId']), function ($query) use ($data) {
                $query->where('employee.id', '=', $data['employeeId']);
            })
            ->when(!empty($data['startTime']) && !empty($data['endTime']), function ($query) use ($data) {
                $query->whereBetween('record.followed_at', [$data['startTime'], $data['endTime']]);
            })
            ->when(!empty($data['orderBy']), function ($query) use ($data) {
                $orderBy=json_decode($data['orderBy'],true);
                if (!empty($orderBy)){
                    $query->orderBy('record.followed_at', str_replace('end','',$orderBy['followedAt']));
                }
            })
            ->leftJoin('work_employee as employee', 'employee.id', 'record.user_id')//user_id记录的是员工id
//            ->leftJoin('user as user','user.id','employee.log_user_id')//user_id记录的是员工id
            ->join('client as client', 'client.id', 'record.client_id')
            ->leftJoin('work_employee as binDingEmployee', 'binDingEmployee.id', 'client.work_employee_id')
            ->select([
                'record.id',//记录id
                'client.id as clientId',
                'employee.name',//员工
                'client.enterprise_name as enterpriseName',//呼叫客户
                'client.b2b_user_type as b2bUserType',//客户等级
                Db::raw('"" as label'),//客户标签
                'binDingEmployee.name as binDingEmployeeName',//绑定员工
                'record.followed_at as followedAt',//跟进时间
                'record.type',//类型（1：电话。2：面访。3：企业微信）
                'record.remark',//跟进内容
            ])
            ->orderByDesc('record.id')
            ->get();
        $list || $list = collect([]);
        $list = $list->toArray();
        if (!empty($list)) {
            foreach ($list as &$datum) {
                $datum->b2bUserType = ClientTypeCode::getMessage($datum->b2bUserType);
                $datum->typeString = ClientFollowRecordTypeCode::getMessage($datum->type);
                $datum->label=[];
            }
            unset($datum);
        }
        return $this->processingToTal($list);
    }

    /**
     * 验证规则.
     *
     * @return array 响应数据
     */
    protected function rules(): array
    {
        return [
        ];
    }

    /**
     * 验证错误提示.
     * @return array 响应数据
     */
    protected function messages(): array
    {
        return [
        ];
    }

    /**
     * 组装基础数据
     * @param $tags
     * @return array
     */

    private function processingToTal($tags): array
    {
        $url = '';
        if (!empty($tags)) {
            $newExcel = new Spreadsheet();  // 创建一个新的excel文档
            $objSheet = $newExcel->getActiveSheet();  // 获取当前操作sheet的对象
            $objSheet->setTitle('跟进列表');  // 设置当前sheet的标题

            // 设置固定宽度，避免 setAutoSize 触发公式计算错误
            $colWidths = [
                'A' => 30,  // 客户名称
                'B' => 15,  // 客户等级
                'C' => 25,  // 客户标签
                'D' => 20,  // 绑定员工
                'E' => 20,  // 跟进员工
                'F' => 20,  // 跟进时间
                'G' => 15,  // 跟进渠道
                'H' => 50,  // 跟进内容
            ];
            foreach ($colWidths as $col => $width) {
                $newExcel->getActiveSheet()->getColumnDimension($col)->setWidth($width);
            }

            // 设置第一栏的标题
            $objSheet->setCellValue('A1', '客户名称')
                ->setCellValue('B1', '客户等级')
                ->setCellValue('C1', '客户标签')
                ->setCellValue('D1', '绑定员工')
                ->setCellValue('E1', '跟进员工')
                ->setCellValue('F1', '跟进时间')
                ->setCellValue('G1', '跟进渠道')
                ->setCellValue('H1', '跟进内容');

            // 数据行
            foreach ($tags as $k => $tag) {
                $k = $k + 2;
                $objSheet->setCellValue('A' . $k, $tag->enterpriseName)
                    ->setCellValue('B' . $k, $tag->b2bUserType)
                    ->setCellValue('C' . $k, empty($tag->label) ? '' : implode(',', $tag->label))
                    ->setCellValue('D' . $k, $tag->binDingEmployeeName)
                    ->setCellValue('E' . $k, $tag->name)
                    ->setCellValue('F' . $k, $tag->followedAt)
                    ->setCellValue('G' . $k, $tag->typeString)
                    ->setCellValue('H' . $k, $tag->remark);
            }

            $url = $this->downloadExcel($newExcel, '跟进列表', 'Xlsx');
        }
        return ['url' => $url];
    }

    public function downloadExcel($newExcel, $filename, $format)
    {
        if ($format == 'Xlsx') {
            header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        } elseif ($format == 'Xls') {
            header('Content-Type: application/vnd.ms-excel');
        }

        header("Content-Disposition: attachment;filename="
            . $filename . date('Y-m-d') . '.' . strtolower($format));
        header('Cache-Control: max-age=0');

        $objWriter = IOFactory::createWriter($newExcel, $format);

        // 🚀 关键：禁用公式预计算，避免 Formula Error
        $objWriter->setPreCalculateFormulas(false);

        $url = BASE_PATH . '/storage/upload/static' . '/跟进列表.xlsx';
        $objWriter->save($url);

        // 以下为 IE 兼容设置，可保留
        header('Cache-Control: max-age=1');
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
        header('Cache-Control: cache, must-revalidate');
        header('Pragma: public');

        return env('DASHBOARD_BASE_URL') . '/api/static/跟进列表.xlsx';
    }

}
